package com.huatai.bpmn.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.huatai.bpmn.commom.util.WechatUtil;
import com.huatai.bpmn.constant.RedisContans;
import com.huatai.bpmn.entity.*;
import com.huatai.bpmn.entity.dto.PageDto;
import com.huatai.bpmn.entity.vo.UserRoleVo;
import com.huatai.bpmn.service.*;
import com.huatai.bpmn.mapper.UserMapper;
import com.huatai.common.api.R;
import com.huatai.common.entity.UserInfo;
import com.huatai.common.httputil.HttpRequest;
import com.huatai.common.util.ObjectUtil;
import com.huatai.common.util.StringUtil;
import com.huatai.user.dto.WeChatPeopleDto;
import com.huatai.user.dubbo.UserDubboApi;
import com.huatai.user.entity.User;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
* @author 聂贞吉
* @description 针对表【tb_user】的数据库操作Service实现
* @createDate 2023-07-12 13:47:44
*/
@Service
@Slf4j
public class UserServiceImpl extends ServiceImpl<UserMapper, UserEntity> implements UserService{

	@Autowired
	private UserService userService;

	@Autowired
	private RoleService roleService;

	@Autowired
	private UserRoleService userRoleService;
	@Value("${gateway.ip}")
	private String ip;

	@Value("${gateway.port}")
	private String port;

	@Value("${gateway.open-api}")
	private String openApi;

	@Value("${gateway.appKey}")
	private String appKey;

	@DubboReference(timeout = 30000,check = false,retries = 0)
	private UserDubboApi userDubboApi;

	@Value("${role.ptjs}")
	private Long ptjs;

	@Value("${role.gljs}")
	private Long gljs;

	@Value("${role.tjjs}")
	private Long tjjs;

	@Value("${role.gsyg}")
	private Long gsyg;

	@Autowired
	private RedisTemplate<String,String> redisTemplate;


	@Override
	public R<String> addUser(UserEntity userEntity) {
		long userId = IdWorker.getId();
		userEntity.setUserId(userId);
		return userService.save(userEntity)==true?R.data("添加用户成功"):R.data("添加用户失败");
	}

	/**
	 * 添加角色
	 * @param roleEntity
	 * @return
	 */
	@Override
	public R<String> addRole(RoleEntity roleEntity) {
		RoleEntity roleOne = roleService.getOne(new LambdaQueryWrapper<RoleEntity>()
			.eq(RoleEntity::getRoleName, roleEntity.getRoleName()));
		if (ObjectUtil.isNotEmpty(roleOne)){
			return R.data("添加失败，该角色名称以存在！");
		}
		long roleId = IdWorker.getId();
		roleEntity.setRoleId(roleId);
		return roleService.save(roleEntity)==true?R.data("添加角色成功"):R.data("添加角色失败");
	}

	/**
	 * 获取用户集合
	 * @param pageDto
	 * @return
	 */
	@Override
	public R<Map<String, Object>> getUserList(PageDto pageDto) {
		Map<String, Object> map = new HashMap<>();
		if (pageDto.getPage().equals(0)&&pageDto.getLimit().equals(0)){
			List<UserEntity> list = userService.list();
			map.put("userList",list);
			map.put("total", list.size());
		}else {
			Page<UserEntity> page = new Page<>(pageDto.getPage(),pageDto.getLimit());
			userService.page(page);
			map.put("userList",page.getRecords());
			map.put("total",page.getTotal());
		}
		return R.data(map);
	}

	/**
	 * 获取角色集合
	 * @param pageDto
	 * @return
	 */
	@Override
	public R<Map<String, Object>> getRoleList(PageDto pageDto) {
		Map<String, Object> map = new HashMap<>();
		if (pageDto.getPage().equals(0)&&pageDto.getLimit().equals(0)){
			List<RoleEntity> list = roleService.list();
			map.put("roleList",list);
			map.put("total", list.size());
		}else {
			Page<RoleEntity> page = new Page<>(pageDto.getPage(), pageDto.getLimit());
			roleService.page(page);
			map.put("roleList", page.getRecords());
			map.put("total", page.getTotal());
		}
		return R.data(map);
	}

	/**
	 * 用户批量添加审批角色
	 * @param userId
	 * @param roleIds
	 * @return
	 */
	@Override
	public R<String> addUserRolesMapping(String userId, String[] roleIds) {
		List<UserRoleEntity> list = userRoleService.list(new LambdaQueryWrapper<UserRoleEntity>()
			.eq(UserRoleEntity::getUserId, userId));
		userRoleService.removeBatchByIds(list);
		for (String roleId : roleIds) {
			UserRoleEntity userRole = new UserRoleEntity();
			userRole.setUserId(userId);
			userRole.setRoleId(roleId);
			userRoleService.save(userRole);
		}
		return R.success("添加角色信息成功");
	}


	/**
	 * 为用户删除绑定的审批角色
	 * @param userId
	 * @param roleId
	 * @return
	 */
	@Override
	public R<String> removeUserRoleMapping(String userId, String roleId) {
		LambdaQueryWrapper<UserRoleEntity> wrapper = new LambdaQueryWrapper<>();
		wrapper.eq(UserRoleEntity::getUserId,userId);
		wrapper.eq(UserRoleEntity::getRoleId,roleId);
		return userRoleService.remove(wrapper)==true?R.data("删除角色成功"):R.data("上传角色失败");
	}

	@Override
	public R<List<UserRoleVo>> findUserRoleList(String userId) {
		List<UserRoleEntity> list = userRoleService.list(new LambdaQueryWrapper<UserRoleEntity>()
			.eq(UserRoleEntity::getUserId, userId));
		List<UserRoleVo> roleList = new ArrayList<>();
		for (UserRoleEntity userRole : list) {
			UserRoleVo userRoleVo = new UserRoleVo();
			userRoleVo.setUserId(userRole.getUserId());
			userRoleVo.setRoleId(userRole.getRoleId());
			userRoleVo.setRoleName(findRoleNameByRoleId(userRole.getRoleId()));
			roleList.add(userRoleVo);
		}
		return R.data(roleList);
	}

	/**
	 * 同步用户信息
	 * @return
	 */
	@Override
	@Transactional(rollbackFor = RuntimeException.class)
	public Boolean syncUsersInfonfo() {
		JSONObject requestBody = new JSONObject();
		requestBody.put("appKey",appKey);
		Optional<JSONObject> resultOpt = HttpRequest
			.post(ip + ":" + port + openApi)
			.bodyString(requestBody.toJSONString())
			.execute()
			.onFailed((request, e) -> log.error("用户同步请求失败:{}", e.getMessage()))
			.onSuccessOpt(responseSpec -> responseSpec.asValue(JSONObject.class));
		JSONObject result = resultOpt.orElse(new JSONObject());
		JSONArray resultDatas = result.getJSONArray("data");
		if (resultDatas == null){
			return false;
		}
		List<UserEntity> updateList = new ArrayList<>(resultDatas.size());
		List<UserRoleEntity> insertUserRole = new ArrayList<>(resultDatas.size());
		LambdaQueryWrapper<UserRoleEntity> userRoleWrapper = Wrappers.lambdaQuery();
		userRoleWrapper
			.select(UserRoleEntity::getUserId)
			.groupBy(UserRoleEntity::getUserId);
		List<UserRoleEntity> roles = userRoleService.list(userRoleWrapper);
		List<String> hasRoleUserIds = roles.stream().map(UserRoleEntity::getUserId).collect(Collectors.toList());
		for (int i = 0; i < resultDatas.size(); i++) {
			JSONObject data = resultDatas.getJSONObject(i);
			UserEntity update = new UserEntity();
			update.setId(data.getLong("id"));
			update.setUserId(data.getLong("id"));
			update.setUserAccount(data.getString("account"));
			update.setUserRealName(data.getString("real_name"));
			if (data.getInteger("is_deleted")==0 && data.getInteger("status")==0) {
				update.setIsDeleted(0);
			}else {
				update.setIsDeleted(1);
			}
			updateList.add(update);
			//添加默认审批角色 公司员工
			if (!hasRoleUserIds.contains(update.getUserId()+"")){
				UserRoleEntity userRole = new UserRoleEntity();
				userRole.setUserId(String.valueOf(update.getUserId()));
				userRole.setRoleId(String.valueOf(gsyg));
				insertUserRole.add(userRole);
			}
		}
		saveOrUpdateBatch(updateList);
		return userRoleService.saveBatch(insertUserRole);
	}

	@Override
	@Transactional(rollbackFor = RuntimeException.class)
	public Boolean syncUsersInfoByWeChat() {
		//判断请求次数
		String syncTimes = redisTemplate.opsForValue().get(RedisContans.SYNC_TIMES);
		if (StringUtil.isEmpty(syncTimes)){
			redisTemplate.opsForValue().set(RedisContans.SYNC_TIMES,"1",600,TimeUnit.SECONDS);
		}else {
			int syncTimeInt = Integer.parseInt(syncTimes);
			redisTemplate.opsForValue().set(RedisContans.SYNC_TIMES,String.valueOf(++syncTimeInt),600,TimeUnit.SECONDS);
			if (syncTimeInt>RedisContans.SYNC_TIMES_LIMIT){
				throw new RuntimeException("同步请求频繁,10分钟后再试");
			}
		}
		//根据token获取操作用户信息
//		UserInfo user = AuthUtil.getUser();
		UserInfo user = new UserInfo();
		user.setUserId(Long.valueOf(3));
		//封装插入用户集合所需参数
		Map<String,Long> roleIdMap = new HashMap<>();
		roleIdMap.put("ptjs",ptjs);
		roleIdMap.put("gljs",gljs);
		roleIdMap.put("tjjs",tjjs);
		Set<WeChatPeopleDto> userSet = new HashSet<>();
		//将从企业微信API获取的数据存入Redis缓存5分钟,避免重复请求API
		String wechatUsersStr = redisTemplate.opsForValue().get(RedisContans.WECHAT_USERS);
		if (StringUtil.isEmpty(wechatUsersStr)){
			userSet = WechatUtil.getList();//用户信息
			if (ObjectUtil.isEmpty(userSet)){
				throw new RuntimeException("可信ip可能已失效，请检查！！");
			}
			redisTemplate.opsForValue().set(RedisContans.WECHAT_USERS,JSONObject.toJSONString(userSet),300L, TimeUnit.SECONDS);
		}else {
			JSONArray wechatArray = JSONObject.parseArray(wechatUsersStr);
			for (int i = 0; i < wechatArray.size(); i++) {
				WeChatPeopleDto wechatUser = wechatArray.getObject(i, WeChatPeopleDto.class);
				userSet.add(wechatUser);
			}
		}
		//通过dubbo调用存取操作
		List<User> newUsers = userDubboApi.saveUserByWeChatUserBpmn(user.getUserId(), userSet, roleIdMap);
		List<UserEntity> updateList = new ArrayList<>(newUsers.size());
		List<UserRoleEntity> insertUserRole = new ArrayList<>(newUsers.size());
		for (User newUser : newUsers) {
			UserEntity update = new UserEntity();
			update.setId(newUser.getId());
			update.setUserId(newUser.getId());
			update.setUserAccount(newUser.getAccount());
			update.setUserRealName(newUser.getRealName());
			if (newUser.getIsDeleted()==0 && newUser.getStatus()==0) {
				update.setIsDeleted(0);
			}else {
				update.setIsDeleted(1);
			}
			updateList.add(update);
			//添加默认审批角色 公司员工
			UserRoleEntity userRole = new UserRoleEntity();
			userRole.setUserId(String.valueOf(update.getUserId()));
			userRole.setRoleId(String.valueOf(gsyg));
			insertUserRole.add(userRole);
		}
		saveOrUpdateBatch(updateList);
		return userRoleService.saveBatch(insertUserRole);
	}

	/**
	 * 修改用户角色名称
	 * @param roleEntity
	 * @return
	 */
	@Override
	public R<String> updateRoleName(RoleEntity roleEntity) {
		LambdaQueryWrapper<RoleEntity> wrapper = new LambdaQueryWrapper<>();
		wrapper.eq(RoleEntity::getRoleId,roleEntity.getRoleId());
		return roleService.update(roleEntity,wrapper)?R.data("更新成功"):R.data("更新失败");
	}

	/**
	 * 根据角色id查找角色名称
	 * @param roleId
	 * @return
	 */
	private String findRoleNameByRoleId(String roleId) {
		RoleEntity role = roleService.getOne(new LambdaQueryWrapper<RoleEntity>()
			.eq(RoleEntity::getRoleId, roleId));
		return role.getRoleName();
	}
}




